/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package staplers;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.NamingContainer;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.servlet.http.HttpServletRequest;
import upload.FacesUtil;
import upload.MultipartRequestWrapper;
import upload.UploadFile;

/**
 *
 * @author robert
 */
@ManagedBean
@SessionScoped
public class ItemCTRL {
    DBHelper helper;
    Item item;
    SearchQuery sq = new SearchQuery();
    DataModel searchResults = null;
    int noSearchAttributes = 0;
    private boolean doUpdate;
    Category categoryToSearch;
    private List itemAttributes;
    private boolean browsing;
    
   
    
    /** Creates a new instance of ItemCTRL */
    public ItemCTRL() {
        helper = ((UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL")).getHelper();
    }

    
    public boolean getBrowsing()
    {
        return browsing;
    }
    
    public Category getCategoryToSearch() {
        return categoryToSearch;
    }

    public void setCategoryToSearch(Category categoryToSearch) {
        this.categoryToSearch = categoryToSearch;
    }

    public boolean isDoUpdate() {
        return doUpdate;
    }   
    
    public SearchQuery getSq() {
        return sq;
    }

    public int getNoSearchAttributes() {
        return noSearchAttributes;
    }

    public String addSearchAttribute()
    {
        noSearchAttributes++;
        return "Search";
    }
   
    public String removeSearchAttribute()
    {
        if (noSearchAttributes>0)
            noSearchAttributes--;
        return "Search";
    }
    
    public Item getItem()
    {
        return item;
    }
    
    
    public String enterInventoryPrep()
    {
        item = new Item();
        itemAttributes = null;
        return "EnterInventory";
    }
    
    public String enterInventory()
    {
        FacesContext ctx = FacesContext.getCurrentInstance();

        Map<String, String> request = ctx.getExternalContext().getRequestParameterMap();
        Iterator iter = getItemAttributes().iterator();
        
        int retValue;
        if (doUpdate) {
            
            retValue = helper.updateItem(item);
            retValue = helper.updateAttributeValues(item.getAttributeValues());
            doUpdate = false;
            ((UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL")).setErrMsg("Item updated");
            return "AdminHome";
        }
        
        retValue= helper.defineNewItem(item);
        if (retValue == -1) {
            item = null;
             ((UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL")).setErrMsg("Uh oh... something went wrong");
            return "InventoryEntry";
        }      
        
        Set<AttributeValue> attributeValues = new HashSet<AttributeValue>(0);
        
        while (iter.hasNext())
        {
            Attribute attribute = (Attribute)iter.next();
            String value = request.get("inventoryEntryForm" + NamingContainer.SEPARATOR_CHAR + "item"+attribute.getId());
            AttributeValue av = new AttributeValue(attribute,item,value);
            attributeValues.add(av);
        }
        
        retValue = helper.defineNewAttributeValues(attributeValues);
        if (retValue == -1) {
            item = null;
            ((UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL")).setErrMsg("Uh oh... something went wrong");
            return "InventoryEntry";
        }
        
        item.setAttributeValues(attributeValues);
        itemAttributes = null;
        
        saveFile(item.getId());
        
        ((UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL")).setErrMsg("Inventory added");
        
        return "AdminHome";
    }
    
    public String selectCategoryBeforeNewItem()
    {
        FacesContext ctx = FacesContext.getCurrentInstance();

        Map<String, String> request = ctx.getExternalContext().getRequestParameterMap();
        
        String _catId = request.get("enterInventoryForm" + NamingContainer.SEPARATOR_CHAR + "category");
        
        Category category = helper.getCategoryById(Integer.parseInt(_catId));
        
        item.setCategory(category);
        
        return "InventoryEntry";
    }
    
    public String searchPrep()
    {
        browsing = false;
        searchResults = null;
        sq = new SearchQuery();
        return "Search1";
    }
    
    public String search()
    {
        FacesContext ctx = FacesContext.getCurrentInstance();

        Map<String, String> request = ctx.getExternalContext().getRequestParameterMap();
        
        Map<String,String> attributeValues = new HashMap<String,String>();
        
        if (noSearchAttributes>0){
            for (int i=1;i<=noSearchAttributes;i++)
            {
                String attributeId = request.get("searchForm" + NamingContainer.SEPARATOR_CHAR + "attribute"+i);
                String attributeValue = request.get("searchForm" + NamingContainer.SEPARATOR_CHAR + "value"+i);
                attributeValues.put(attributeId, attributeValue);
            }
            sq.setAttributeValues(attributeValues);
        }
        noSearchAttributes = 0;
       return "Search2";
    }
    
    
    public DataModel getSearchResults()
    {
        
        if (searchResults == null){
            List list = helper.search(sq);
            if (list == null)
                return null;
            else
                searchResults = new ListDataModel(list);
        }
              
        return searchResults;
    }
    
    public String prepareItemView()
    {
        UserCTRL userBean = (UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL");
        item = (Item)getSearchResults().getRowData();
        if (userBean.getUser().getIsAdmin())
            return "AdminItem";
        else
            return "ItemPage";
    }
    
    public String deleteItem()
    {
        helper.deleteItem(item);
        item = null;
        ((UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL")).setErrMsg("Item deleted");
        return "AdminHome";
    }
    
    public String updateItem()
    {
        doUpdate = true;
//        ((UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL")).setErrMsg("Item updated");
        return "InventoryEntry";
    }
    
    public String updateStockPrep()
    {
        return "UpdateStock";
    }
    
    public String updateStock()
    {
        helper.updateItem(item);
        ((UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL")).setErrMsg("Stock amount updated");
        return "AdminHome";
    }
    
    public String browsePrep()
    {
        browsing = true;
        sq = new SearchQuery();
        CategoryCTRL cc;
        if ((cc = ((CategoryCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("categoryCTRL")))!=null)
            cc.resetCategory();
        searchResults = new ListDataModel(helper.getAllItems());
        return "Search2";
    }
    
    public String selectCategoryToSearch()
    {
        FacesContext ctx = FacesContext.getCurrentInstance();

        Map<String, String> request = ctx.getExternalContext().getRequestParameterMap();
        
        String _catList = request.get("catList" + NamingContainer.SEPARATOR_CHAR + "category");
        int category = Integer.parseInt(_catList);
        if (category==-1)
        {
            sq = new SearchQuery();
            categoryToSearch = null;
            searchResults = new ListDataModel(helper.getAllItems());
            return "Search2";
        }
        Category cat = helper.getCategoryById(category);
        this.categoryToSearch= cat;
        sq = new SearchQuery();
        List<Item> list = getItemsByCategory(new ArrayList<Item>(), cat);
        Collections.sort(list, new Item());
        searchResults = new ListDataModel(list);
        return "Search2";
    }
    
    private List getItemsByCategory(List list, Category cat)
    {
        list.addAll(helper.getItemsByCategory(cat));
        for (Category category : cat.getCategoriesForCategoryOf())
        {
            getItemsByCategory(list,category);
        }
        return list;
    }
    
    public String changeCategory()
    {
        itemAttributes = null;
        FacesContext ctx = FacesContext.getCurrentInstance();

        Map<String, String> request = ctx.getExternalContext().getRequestParameterMap();
        
        String _catList = request.get("catList" + NamingContainer.SEPARATOR_CHAR + "category");
        int category = Integer.parseInt(_catList);
        if (category == -1)
            return "AdminItem";
        Category cat = helper.getCategoryById(category);
        item.setCategory(cat);        
        helper.updateItem(item);
        helper.deleteAttributesByItemId(item.getId());

        HashSet<AttributeValue> newAttributeValues = new HashSet<AttributeValue>(0);
        for (Attribute attribute : getItemAttributes())
        {
            newAttributeValues.add(new AttributeValue(attribute,item,""));
        }
        helper.defineNewAttributeValues(newAttributeValues);
        
        item.setAttributeValues(newAttributeValues);
        ((UserCTRL)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userCTRL")).setErrMsg("Please enter the new required attributes for this category");
        return "InventoryEntry";
        
    }
    
    public List<Attribute> getItemAttributes()
    {
        
        itemAttributes = getAllAttributesForItem(new ArrayList<Attribute>(),item.getCategory().getId());
        return itemAttributes;
    }

    private List getAllAttributesForItem(List list, int categoryId) {
        list.addAll(helper.getAttributesForCategory(categoryId));
        Category category = helper.getCategoryById(categoryId);
        if (category.getCategoryByCategoryOf()!= null)
            getAllAttributesForItem(list,category.getCategoryByCategoryOf().getId());
        return list;
    }
    
    public void saveFile(int itemId) {
        // Make use of session for example. No need to complicate with connection to filesystem or database
        HttpServletRequest req = FacesUtil.getRequest();
        UploadFile uf = null;
        String fileName = itemId+"";
        if (req instanceof MultipartRequestWrapper) {
            MultipartRequestWrapper multi = (MultipartRequestWrapper) req;

            uf = multi.findFile("imageFile");
            if (uf != null) {
                String fileExt = uf.getFileName().substring(uf.getFileName().lastIndexOf("."));
                fileName += fileExt;
                System.out.println("Extension" + fileExt);
                // should actually check the extension, but no big deal for example
            }
        }

        FileOutputStream fos;
        try {
            String path = "C:\\pub\\images\\items\\" + fileName;//(FacesContext.getCurrentInstance().getExternalContext().getRealPath("/"));
            //path+=/*"../../web/*/"images/models/"+fileName;
            System.out.println(path);
            fos = new FileOutputStream(path);
            fos.write(uf.getFileData());
            fos.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
